#include <iostream>
#include <thread>
#include <queue>
#include <vector>
#include <mutex>
#include <condition_variable>

#define THREAD_NUM 10
template <class T>
class threadPool
{
public:
    static void fun(threadPool<T> *ts)
    {
        std::unique_lock<std::mutex> lock(ts->mtx_);
        while (1)
        {
            if (ts->task_.empty())
            {
                ts->con_.wait(lock);
            }
            T t = ts->task_.front();
            ts->task_.pop();
            t();
        }
    }
    void init()
    {
        for (auto &e : th_)
        {
            e = thread(fun, this);
        }
    }
    static threadPool<T> *getInstance()
    {
        if (ptr_ == nullptr)
        {
            std::unique_lock<std::mutex> lock(mt_);
            if (ptr_ == nullptr)
            {
                ptr_ = new threadPool();
            }
        }
        return ptr_;
    }

    void push(T &t)
    {
        unique_lock<mutex> lock(mtx_);
        task_.push(t);
        con_.notify_one();

    }

private:
    threadPool(int thread_num = THREAD_NUM)
        : th_(thread_num)
    {
    }
    ~threadPool()
    {
    }
    std::queue<T> task_;
    std::vector<thread> th_;
    std::mutex mtx_;
    std::condition_variable con_;
    // 单例模式
    static threadPool<T> *ptr_;
    static std::mutex mt_;
};

template <class T>
threadPool<T> *threadPool<T>::ptr_ = nullptr;

template <class T>
std::mutex threadPool<T>::mt_;